package com.xjx.controller;

import cn.hutool.core.util.RandomUtil;
import com.xjx.common.Result;
import com.xjx.model.User;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;


@RestController
@RequestMapping("/hutool")
public class HutoolController {

    private static final String UPLOAD_PATH = "/home/catlina/Share/";

    /**
     * Hutool文件上传接口
     * 接收一个MultipartFile文件，并使用Hutool的FileUtil将其保存到指定目录。
     * 为了防止文件重名，使用IdUtil生成唯一文件名。
     *
     * @param file 前端上传的文件
     * @return 包含上传结果信息的Result对象
     */
    @PostMapping("/upload")
    public Result<String> upload(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return Result.failure("文件为空，请选择文件");
        }
        try {
            // 获取原始文件名
            String originalFilename = file.getOriginalFilename();
            // 生成唯一文件名，防止重名
            String newFilename = IdUtil.fastSimpleUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
            File dest = new File(UPLOAD_PATH, newFilename);

            // 使用Hutool的FileUtil将上传文件的字节写入目标文件
            FileUtil.writeBytes(file.getBytes(), dest);

            return Result.success("文件上传成功，保存路径：" + dest.getAbsolutePath());
        } catch (IOException e) {
            e.printStackTrace();
            return Result.failure("文件上传失败：" + e.getMessage());
        }
    }

    /**
     * Hutool日期格式化接口
     * 使用DateUtil将接收的日期字符串按指定格式进行转换。
     * Hutool的DateUtil能够自动识别多种常见日期格式进行解析。
     *
     * @param dateStr   日期字符串，如"2023-01-01"
     * @param formatStr 格式化模式，如"yyyy年MM月dd日"
     * @return 格式化后的日期字符串的Result对象
     */
    @GetMapping("/formatDate")
    public Result<String> formatDate(@RequestParam String dateStr, @RequestParam String formatStr) {
        try {
            // 解析日期字符串为Date对象
            var date = DateUtil.parse(dateStr);
            // 格式化日期为指定格式的字符串
            String formattedDate = DateUtil.format(date, formatStr);
            return Result.success(formattedDate);
        } catch (Exception e) {
            // 使用更具体的错误码和信息
            return Result.fail(400, "日期或格式不正确，请检查输入：" + e.getMessage());
        }
    }

    /**
     * Hutool加密接口
     * 使用SecureUtil对传入的明文字符串进行MD5或SHA1加密。
     * SecureUtil封装了多种加密算法，使用简单。
     *
     * @param plainText 需要加密的明文
     * @param algorithm 加密算法类型，可选"MD5"或"SHA1"
     * @return 加密后的字符串的Result对象
     */
    @GetMapping("/encrypt")
    public Result<String> encrypt(@RequestParam String plainText, @RequestParam String algorithm) {
        String result;
        switch (algorithm.toUpperCase()) {
            case "MD5":
                result = SecureUtil.md5(plainText);
                break;
            case "SHA1":
                result = SecureUtil.sha1(plainText);
                break;
            default:
                return Result.failure("不支持的加密算法类型，目前只支持MD5和SHA1");
        }
        return Result.success(result);
    }

    /**
     * Hutool JSON转换接口
     * 接收一个Java对象（这里以User为例），并使用JSONUtil将其转换为JSON字符串。
     * JSONUtil提供了对象和JSON字符串之间便捷的相互转换方法。
     *
     * @param user 需要转换的User对象
     * @return 转换后的JSON字符串的Result对象
     */
    @PostMapping("/toJson")
    public Result<String> toJson(@RequestBody User user) {
        if (user == null) {
            return Result.failure("请求体为空");
        }
        String jsonString = JSONUtil.toJsonStr(user);
        return Result.success(jsonString);
    }

    /**
     * Hutool随机字符串生成接口
     * 使用RandomUtil根据指定长度和类型生成随机字符串。
     *
     * @param length 字符串长度
     * @param type   类型，可选"all"（默认）、"number"、"string"
     * @return 随机生成的字符串的Result对象
     */
    @GetMapping("/randomStr")
    public Result<String> generateRandomString(@RequestParam int length, @RequestParam(defaultValue = "all") String type) {
        String randomStr;
        switch (type.toLowerCase()) {
            case "number":
                randomStr = RandomUtil.randomNumbers(length);
                break;
            case "string":
                randomStr = RandomUtil.randomString(length);
                break;
            case "all":
            default:
                randomStr = RandomUtil.randomString(RandomUtil.BASE_CHAR_NUMBER, length);
                break;
        }
        return Result.success(randomStr);
    }
}

